Skip to content

Use effects for indirect call expressions#8625

Open
stevenfontanella wants to merge 3 commits intomainfrom
expression-effects
Open

Use effects for indirect call expressions#8625
stevenfontanella wants to merge 3 commits intomainfrom
expression-effects

Conversation

@stevenfontanella
Copy link
Copy Markdown
Member

@stevenfontanella stevenfontanella commented Apr 19, 2026

Part of #8615. After #8609, we compute effects for indirect call expressions, but only reflect this in the call-site via the effects of the Function that contains the indirect call. That let us reason about effects only one layer of indirection away, for example in the following module:

(func $a
  (call_ref $t (...))
)

(func $b
  (call $a)
)

If we know that an indirect call to $t can't possibly have any effects (e.g. its only potential target is a nop), we'd be able to optimize away (call $a) but not the (call_ref) itself, since the effects only got stored in the effects of $a.

This PR lets us reason about indirect call effects at the expression level within function bodies by adding a map from HeapType to effects typeEffects in wasm::Module. As a result we can completely optimize out the call_ref in the above example.

Comment thread src/ir/effects.h Outdated
@stevenfontanella
Copy link
Copy Markdown
Member Author

Seems like JJ + Github don't play well when I'm on a branch based on another branch that had a merge commit. Will fix this after merging the other branch.

stevenfontanella added a commit that referenced this pull request Apr 24, 2026
When running in --closed-world, compute effects for indirect calls by
unioning the effects of all potential functions of that type. In
--closed-world, we assume that all references originate in our module,
so the only possible functions that we don't know about are imports.
Previously [we gave up on effects
analysis](https://github.com/WebAssembly/binaryen/blob/29b2d42e8a748fbe1095696d58a52b7bf83e2253/src/passes/GlobalEffects.cpp#L83-L87)
for indirect calls.

Yields a very small byte count reduction in calcworker (3799354 -
3799297 = 57 bytes). Also shows no significant difference in Binaryen
runtime: (0.1346069 -> 0.13375045 = <1% improvement, probably within
noise). We expect more benefits after we're able to share indirect call
effects with other passes, since currently they're only seen one layer
up for callers of functions that indirectly call functions (see the
newly-added tests for examples).

Followups:
* Share effect information per type with other passes besides just via
Function::effects (#8625)
* Exclude functions that don't have an address (i.e. functions that
aren't the target of ref.func) from effect analysis ()
* Compute effects more precisely for exact + nullable/non-nullable
references

Part of #8615.
Base automatically changed from indirect-effects-scc to main April 24, 2026 21:36
@stevenfontanella stevenfontanella force-pushed the expression-effects branch 3 times, most recently from 30a31e1 to 60665f3 Compare May 7, 2026 20:33
Gemini WIP

Try changing call effects
@stevenfontanella stevenfontanella marked this pull request as ready for review May 7, 2026 21:33
@stevenfontanella stevenfontanella requested a review from a team as a code owner May 7, 2026 21:33
@stevenfontanella stevenfontanella requested review from aheejin and removed request for a team May 7, 2026 21:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants